package com.ttbj.product.company.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.ttbj.api.company.CompanyService;
import com.ttbj.api.dto.AccManageData;
import com.ttbj.api.dto.CompanyDto;
import com.ttbj.api.dto.Page;
import com.ttbj.api.dto.SalesmanDto;
import com.ttbj.api.exception.BusinessException;
import com.ttbj.api.yitong.YTFinancialService;
import com.ttbj.company.bean.po.Company;
import com.ttbj.company.dao.CompanyMapper;
import com.ttbj.constant.AccTypeEnum;
import com.ttbj.constant.CompanyEnum;
import com.ttbj.constant.GenerateNumConstants;
import com.ttbj.constant.PlatFormErrorCode;
import com.ttbj.constant.annotation.SystemServiceLog;
import com.ttbj.core.util.DtoTransitionUtils;
import com.ttbj.core.util.JsonUtil;
import com.ttbj.core.util.MarkNumUtil;
import com.ttbj.product.util.CompanyNumUtil;
import com.ttbj.salesman.dao.SalesmanMapper;



@Service("companyService")
public class CompanyServiceImpl implements CompanyService{
	
	@Autowired
	private CompanyMapper companyMapper; 
	@Autowired
	private SalesmanMapper salesmanMapper;
	@Autowired
	private YTFinancialService ytFinancialService;
	
	private static final Logger logger = LoggerFactory.getLogger(CompanyServiceImpl.class);
	
	@Override
	public List<CompanyDto> findCompanyNumAndName(SalesmanDto salesmanDto) throws BusinessException {
		String companyNum = salesmanDto.getSalesmanComnum();
		List<Company> companies = this.companyMapper.queryCompanyNumAndName(companyNum, CompanyEnum.NOT_DELETE.getCode());
		List<CompanyDto> companyDtos = new ArrayList<>();
		for (Company company : companies) {
			CompanyDto cDto = (CompanyDto) DtoTransitionUtils.trans(CompanyDto.class, company);
			companyDtos.add(cDto);
		}
		return companyDtos;
	}
	
	@Override
	@Cacheable(value="usedEdit",key="#root.methodName")
	public List<CompanyDto> findCompanyNumAndNameUsedSelect() throws BusinessException {
		List<Company> companies = this.companyMapper.queryCompanyNumAndNameUsedSelect(CompanyEnum.NOT_DELETE.getCode());
		List<CompanyDto> companyDtos = new ArrayList<>();
		for (Company company : companies) {
			CompanyDto cDto = (CompanyDto) DtoTransitionUtils.trans(CompanyDto.class, company);
			companyDtos.add(cDto);
		}
		return companyDtos;
	}

	@Override
	public List<CompanyDto> findCompanyPage(Page page, CompanyDto companyDto) throws BusinessException {
		Company company = (Company) DtoTransitionUtils.trans(Company.class, companyDto);
		List<Company> companyList = this.companyMapper.queryCompaynPage(page, company);
		List<CompanyDto> companyDtos = new ArrayList<>();
		for (Company cp : companyList) {
			CompanyDto cDto = (CompanyDto) DtoTransitionUtils.trans(CompanyDto.class, cp);
			companyDtos.add(cDto);
		}
		return companyDtos;
	}

	@Override
	public Integer findCompanyPageCount(CompanyDto companyDto) throws BusinessException {
		Company company = (Company) DtoTransitionUtils.trans(Company.class, companyDto);
		Integer count = this.companyMapper.queryCompaynPageCount(company);
		return count;
	}

	@Override
	@Transactional
	@CacheEvict(value="usedEdit",key="'findCompanyIdAndName'")
	@SystemServiceLog(description="增加公司信息")
	public CompanyDto addCompanyInfo(CompanyDto companyDto) throws BusinessException {
		if (null == companyDto) {
			throw new BusinessException("数据有错误！", PlatFormErrorCode.OBJECT_DOES_NOT_EXIST.code());
		}
		Company company = (Company) DtoTransitionUtils.trans(Company.class, companyDto);
		//设置公司编号.GenerateNumConstants.COMPANY 是前缀
		String companyNum = CompanyNumUtil.getNo(GenerateNumConstants.COMPANY);
		//设置公司编号
		company.setComnumNum(companyNum);
		//设置插入时间
		company.setComnumInsTime(new Date());
		//设置公司状态（0 是未停运，1 已停运），未停运状态
		company.setComnumIsDelete(CompanyEnum.NOT_DELETE.getCode());
		//执行保存到数据库操作
		int result = this.companyMapper.insertCompanInfo(company);
		if (result == 0) {
			throw new BusinessException("数据有错误，增加公司失败！", PlatFormErrorCode.DATA_SECURITY.code());
		}
		
		/*下面以及返回CompanyDto对象，为了小程序*/
		logger.info("公司的ID是：{}，公司的编号是：{}", company.getComnumId(), companyNum);
		companyDto = new CompanyDto();	//重新new一个，否则带有其他属性的值
		companyDto.setComnumId(company.getComnumId());	//获取返回的主键ID
		companyDto.setComnumNum(companyNum);	//获取生成的公司编号
		return companyDto;
	}
	
	@Override
	public CompanyDto findCompanyById(Long companyId) throws BusinessException {
		Company company = this.companyMapper.queryCompanyById(companyId);
		CompanyDto companyDto = (CompanyDto) DtoTransitionUtils.trans(CompanyDto.class, company);
		return companyDto;
	}
	
	@Override
	@Transactional
	@CacheEvict(value="usedEdit",key="'findCompanyIdAndName'")
	@SystemServiceLog(description="修改公司信息")
	public void editCompanyInfo(CompanyDto companyDto) throws BusinessException {
		if (null == companyDto) {
			throw new BusinessException("数据有错误！", PlatFormErrorCode.OBJECT_DOES_NOT_EXIST.code());
		}
		Company company = (Company) DtoTransitionUtils.trans(Company.class, companyDto);
		//设置更新时间
		company.setComnumUpdateTime(new Date());
		this.companyMapper.updateCompanyInfo(company);
	}

	@Override
	@Transactional
	@SystemServiceLog(description="修改公司停运状态")
	public void editCompanyDisable(Integer isDelete, Long comnumId, String companyNum) throws BusinessException {
		if (null == isDelete || null == comnumId) {
			throw new BusinessException("数据有错误！", PlatFormErrorCode.DATA_SECURITY.code());
		}
		//查询本公司下有没有分公司
		List<Long> branchComnumIds = this.companyMapper.queryBranchCompanyIdList(comnumId);
		//如果有分公司
		if (null != branchComnumIds && branchComnumIds.size() > 0) {
			//把总公司的id也放入list中
			branchComnumIds.add(comnumId);
			//更新总公司以及分公司的状态
			this.companyMapper.updateBranchCompanyDisable(isDelete, branchComnumIds);
		}else {	//如果没有分公司
			//使用companyNum 公司编号，查询本公司是否存在用户
			Integer count = this.salesmanMapper.querySalesmanCountByComnum(companyNum);
			//如果count为0，说明业务员表中无本公司的用户
			if (count == 0) {
				this.companyMapper.updateCompanyDisable(isDelete, comnumId);
			}else {	//count不为0，说明业务员表中有本公司的用户
				this.companyMapper.updateJoinCompanyDisable(isDelete, comnumId);
			}
		}
	}


	@Override
	public List<CompanyDto> findBranchCompaynInfo(Page page, Long companyId) throws BusinessException {
		List<Company> companyList = this.companyMapper.queryBranchCompayInfo(page, companyId);
		List<CompanyDto> companyDtos = new ArrayList<>();
		for (Company company : companyList) {
			CompanyDto cDto = (CompanyDto) DtoTransitionUtils.trans(CompanyDto.class, company);
			companyDtos.add(cDto);
		}
		return companyDtos;
	}

	@Override
	public Integer findBranchCompanyInfoCount(Long companyId) throws BusinessException {
		Integer count = this.companyMapper.queryBranchCompayInfoCount(companyId);
		return count;
	}

	@Override
	public List<Long> findBranchCompanyIdList(Long companyId) throws BusinessException {
		List<Long> branchCompanyIds = this.companyMapper.queryBranchCompanyIdList(companyId);
		return branchCompanyIds;
	}

	@Override
	@Transactional
	@SystemServiceLog(description="修改分公司信息")
	public void editBranchCompanyInfo(CompanyDto companyDto, List<Long> companyIds) throws BusinessException {
		Company company = (Company) DtoTransitionUtils.trans(Company.class, companyDto);
		this.companyMapper.updateBranchCompanyInfo(company, companyIds);
	}

	@Override
	public Long findCompanyIdByNum(String comnumNum) throws BusinessException {
		Long companyId = this.companyMapper.queryCompanyIdByNum(comnumNum);
		return companyId;
	}

	@Override
	public List<String> findBranchCompanyNum(String comnumNum) throws BusinessException {
		List<String> branchCompanyNums = this.companyMapper.queryBranchCompanyNum(comnumNum);
		return branchCompanyNums;
	}

	@Override
	public List<CompanyDto> findBranchCompanyIdAndName(String comnumNum) throws BusinessException {
		if (null == comnumNum) {
			throw new BusinessException("数据有错误！", PlatFormErrorCode.PARAM_IS_NULL.code());
		}
		List<Company> companies = this.companyMapper.queryBranchCompanyIdAndName(comnumNum);
		List<CompanyDto> dCompanyDtos = new ArrayList<>();
		for (Company company : companies) {
			CompanyDto cDto = (CompanyDto) DtoTransitionUtils.trans(CompanyDto.class, company);
			dCompanyDtos.add(cDto);
		}
		return dCompanyDtos;
	}
	
	@Override
	public CompanyDto findCompanyOpenAccInfo(Long comnumId) throws BusinessException {
		if (null == comnumId) {
			throw new BusinessException("数据有错误！", PlatFormErrorCode.PARAM_IS_NULL.code());
		}
		Company company = this.companyMapper.queryCompanyOpenAccById(comnumId);
		if (null == company) {
			throw new BusinessException("公司不存在，打开错误！", PlatFormErrorCode.OBJECT_DOES_NOT_EXIST.code());
		}
		CompanyDto companyDto = (CompanyDto) DtoTransitionUtils.trans(CompanyDto.class, company);
		return companyDto;
	}

	@Override
	public void addCompanyOpenAcc(CompanyDto companyDto) throws BusinessException {
		if (null == companyDto) {
			throw new BusinessException("数据有错误！", PlatFormErrorCode.OBJECT_DOES_NOT_EXIST.code());
		}
		Company company = (Company) DtoTransitionUtils.trans(Company.class, companyDto);
		AccManageData accManageData = null;
		//获取公司类型
		String companyType = company.getComnumType();
		//如果是选择的对私
		if (AccTypeEnum.TO_PRIVATE.getDesc().equals(companyType)) {
			accManageData = new AccManageData();
			accManageData.setCustNo(company.getComnumNum());	//使用编号来设置客户号
			accManageData.setAccType(companyType);	//设置账户类型：00对私，01对公
			accManageData.setAccBank(company.getComnumBankName());	//设置开户银行如：中国银行
			accManageData.setCardNo(company.getComnumBankCard());	//设置银行卡号
			accManageData.setCardName(company.getComnumBankHolder());	//设置持卡人姓名
			accManageData.setIdNo(company.getComnumIdCard());	//设置身份证号
			accManageData.setMobileNo(company.getComnumPhone());	//设置手机号
		}else if (AccTypeEnum.TO_PUBLIC.getDesc().equals(companyType)) {	//如果是选择的对公
			accManageData = new AccManageData();
			accManageData.setCustNo(company.getComnumNum());	//使用编号来设置客户号
			accManageData.setAccType(companyType);	//设置账户类型：00对私，01对公
			accManageData.setAccBank(company.getComnumBankName());	//设置开户银行如：中国银行
			accManageData.setCorpName(company.getComnumName());	//设置企业名称
			accManageData.setCorpCode(company.getComnumLicenceCode());	//设置企业统一信用代码
			accManageData.setCorpAccNo(company.getComnumBankCard());	//企业银行账号
			accManageData.setInterBankNo(company.getComnumInterBankNo());	//开户行联行行号
			accManageData.setBankArea(company.getComnumBankArea());	//设置开户行地址
		}else {
			throw new BusinessException("选择错误，只能选择对私或对公！", PlatFormErrorCode.DATA_SECURITY.code());
		}
		//调用接口进行开户操作
		Map<String, String> resultMap = null;
		try {
			logger.info("开户请求的参数为{}", accManageData.toString());
			resultMap = this.ytFinancialService.getYTFinancialResult(accManageData, 10, "open_acc");
		} catch (Exception e) {
			e.printStackTrace();
		}
		//如果返回的是1，则说明账户开户成功
		if (null != resultMap && "1".equals(resultMap.get("status"))) {
			//根据data节点，解析json字符串为 AccManageData 对象
			accManageData = (AccManageData) JsonUtil.jsonToBean(resultMap.get("data"), "data", AccManageData.class);
			//获取账户号并设置
			company.setComnumAccountNo(accManageData.getAccountNo());
			int i = this.companyMapper.insertCompanyOpenAcc(company);
			//如果i为0，说明是没有增加成功
			if (i == 0) {
				logger.info("保存开户信息失败，开户信息为：{}", accManageData.toString());
				throw new BusinessException("保存开户信息失败，人工处理！", PlatFormErrorCode.DATA_SECURITY.code());
			}
		}else {
			logger.info("账户开户--->{}", resultMap.get("data"));
			//通过 | 分割成数组，获取返回的提示信息
			String message = com.ttbj.core.util.StringUtil.split(resultMap.get("data"), "|")[1];
			throw new BusinessException(message, PlatFormErrorCode.DATA_SECURITY.code());
		}
	}

	@Override
	public void editCompanyAccModify(CompanyDto companyDto) throws BusinessException {
		if (null == companyDto) {
			throw new BusinessException("数据有错误！", PlatFormErrorCode.OBJECT_DOES_NOT_EXIST.code());
		}
		AccManageData accManageData = null;
		//获取公司类型
		String companyType = companyDto.getComnumType();
		//如果是选择的对私
		if (AccTypeEnum.TO_PRIVATE.getDesc().equals(companyType)) {
			accManageData = new AccManageData();
			accManageData.setAccountNo(companyDto.getComnumAccountNo());//设置账户号
			accManageData.setAccType(companyType);	//设置账户类型：00对私，01对公
			accManageData.setAccBank(companyDto.getComnumBankName());	//设置开户银行如：中国银行
			accManageData.setCardNo(companyDto.getComnumBankCard());	//设置银行卡号
			accManageData.setMobileNo(companyDto.getComnumPhone());	//设置手机号
			accManageData.setAddiData(companyDto.getComnumAddiData());	//附加数据
		}else if (AccTypeEnum.TO_PUBLIC.getDesc().equals(companyType)) {	//如果是选择的对公
			accManageData = new AccManageData();
			accManageData.setAccountNo(companyDto.getComnumAccountNo());//设置账户号
			accManageData.setAccType(companyType);	//设置账户类型：00对私，01对公
			accManageData.setAccBank(companyDto.getComnumBankName());	//设置开户银行如：中国银行
			accManageData.setCorpAccNo(companyDto.getComnumBankCard());	//企业银行账号
			accManageData.setAddiData(companyDto.getComnumAddiData());	//附加数据
		}else {
			throw new BusinessException("选择错误，只能选择对私或对公！", PlatFormErrorCode.DATA_SECURITY.code());
		}
		//调用接口进行账户变更操作
		Map<String, String> resultMap = null;
		try {
			resultMap = this.ytFinancialService.getYTFinancialResult(accManageData, 10, "acc_modify");
		} catch (Exception e) {
			e.printStackTrace();
		}
		//如果返回的是1，则说明账户变更成功
		if (null != resultMap && "1".equals(resultMap.get("status"))) {
			//根据data节点，解析json字符串为 AccManageData 对象
			accManageData = (AccManageData) JsonUtil.jsonToBean(resultMap.get("data"), "data", AccManageData.class);
			logger.info("账户变更正常---{}", resultMap.get("data"));
			//获取新账户号并更新
			companyDto.setComnumAccountNo(accManageData.getAccountNo());
			Company company = (Company) DtoTransitionUtils.trans(Company.class, companyDto);
			int i = this.companyMapper.insertCompanyOpenAcc(company);
			//如果i为0，说明是没有增加成功
			if (i == 0) {
				logger.info("保存变更信息失败，变更后的账户号：{}", accManageData.getAccountNo());
				throw new BusinessException("账户变更更新失败，人工处理！", PlatFormErrorCode.DATA_SECURITY.code());
			}
		}else {
			logger.info("账户变更异常--->{}", resultMap.get("data"));
			//通过 | 分割成数组，获取返回的提示信息
			String message = com.ttbj.core.util.StringUtil.split(resultMap.get("data"), "|")[1];
			throw new BusinessException(message, PlatFormErrorCode.DATA_SECURITY.code());
		}
	}

	@Override
	public String findWdPasswordByNum(String comnumNum) {
		String wdPassword = this.companyMapper.queryWdPasswordByNum(comnumNum);
		return wdPassword;
	}

	@Override
	public String findComnumAccountNoByNum(String comnumNum) {
		String accountNo = this.companyMapper.queryComnumAccountNoByNum(comnumNum);
		return accountNo;
	}

	@Override
	public CompanyDto findBankCardAndNameByNum(String comnumNum) {
		Company company = this.companyMapper.queryBankCardAndNameByNum(comnumNum);
		CompanyDto companyDto = (CompanyDto) DtoTransitionUtils.trans(CompanyDto.class, company);
		return companyDto;
	}

}
